package org.imixs.manik.webstat.ejb;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
import java.util.logging.Logger;

/**
 * // Source: src/main/java/net/sf/jtmt/concurrent/hadoop/NcsaLogParser.java
 * 
 * @see http://sujitpal.blogspot.com/2009/06/some-access-log-parsers.html
 * 
 *      A stripped down version of the NCSA Log parser. There is no attempt to
 *      identify the fields here. The log line is tokenized by whitespace,
 *      unless the current token begins with a quote (ie multi word fields such
 *      as user_agent) or with a square bracket (ie datetime group). Caller is
 *      responsible for identifying which token to use. Using this approach
 *      simplifies the logic a lot, and also ensures that only the processing
 *      that is absolutely necessary get done, ie we are not spending cycles to
 *      parse out the contents of the datetime or the request group unless we
 *      want to. If we do, then the parsing is done in the caller code - at this
 *      point, the extra parsing can be as simple as calling String.split() with
 *      the appropriate delimiters.
 * 
 * @author Sujit Pal , rsoika
 * 
 */
public class NcsaLogParser {
	private static Logger logger = Logger.getLogger("org.imixs.manik.webstat");

	
	public static List<String> parse(String logline) {
		List<String> tokens = new ArrayList<String>();
		StringBuilder buf = new StringBuilder();
		char[] lc = logline.toCharArray();
		boolean inQuotes = false;
		boolean inBrackets = false;
		for (int i = 0; i < lc.length; i++) {
			if (lc[i] == '"') {
				inQuotes = inQuotes ? false : true;
			} else if (lc[i] == '[') {
				inBrackets = true;
			} else if (lc[i] == ']') {
				if (inBrackets) {
					inBrackets = false;
				}
			} else if (lc[i] == ' ' && (!inQuotes) && (!inBrackets)) {
				tokens.add(buf.toString());
				buf = new StringBuilder();
			} else {
				buf.append(lc[i]);
			}
		}
		if (buf.length() > 0) {
			tokens.add(buf.toString());
		}
		return tokens;
	}

	/**
	 * Parser for the datetime string in a accesslog entry. The expected format
	 * is:
	 * 
	 * <code>
	  dd/MMM/yyyy:hh:mm:ss +-hhmm
	 * </code>
	 * 
	 * @see http
	 *      ://publib.boulder.ibm.com/tividd/td/ITWSA/ITWSA_info45/en_US/HTML
	 *      /guide/c-logs.html#ncsa
	 * @param adate
	 * @return
	 */
	public static Calendar parseDateString(String adate) {
		Date thedate;
		
		try {
			// dd/MMM/yyyy:hh:mm:ss +-hhmm
			// "04/Dec/2009:15:43:54 +0100"
			
			/*
			 *Here we are changing the Time Zone - seems to be necessary to be configurable... :-/
			 */
			 TimeZone cetTime = TimeZone.getTimeZone("CET");
			 
			 // we strip also the timezone offset : "dd/MMM/yyyy:hh:mm:ss Z"
			 // so we do ignore the String part '+0100'
			 DateFormat cetFormat =  new SimpleDateFormat("dd/MMM/yyyy:hh:mm:ss",Locale.ENGLISH);
			 cetFormat.setTimeZone(cetTime);
			 
			thedate =cetFormat.parse(adate);
		} catch (ParseException e) {

			//e.printStackTrace();
			logger.warning(e.getMessage());
			return null;
		}

		Calendar cal=Calendar.getInstance();
		cal.setTime(thedate);
		return cal;
	}
}
